package com.forever7776.life.web.config.websocket;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.web.socket.WebSocketSession;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 通道
 *
 * @author kz
 * @date 2018/03/28
 */
public class WebSocketChannel {

    /**
     * 控制器通道
     */
    private static final Map<String, WebSocketSession> CTRL_CHANNELS = Maps.newConcurrentMap();

    /**
     * 大屏通道,一个控制器可以控制多个大屏 key规则:channelName_sessionId
     */
    private static final Map<String, WebSocketSession> SCREEN_CHANNELS = Maps.newConcurrentMap();

    /**
     * 大屏通道 通道与sessionId关系
     */
    private static final Map<String, List<String>> SCREEN_CHANNELS_SESSIONID = Maps.newConcurrentMap();


    public static void addCtrlChannel(String channelName, WebSocketSession webSocketSession) {
        CTRL_CHANNELS.put(channelName, webSocketSession);
    }

    public static void delCtrlChannel(String channelName) {
        CTRL_CHANNELS.remove(channelName);
    }

    public static boolean isExistsCtrlChannel(String channelName) {
        return CTRL_CHANNELS.containsKey(channelName);
    }


    public static void addScreenChannel(String channelName, WebSocketSession webSocketSession) {
        String sessionId = webSocketSession.getId();
        String key = getScreenChannelKey(channelName, sessionId);
        SCREEN_CHANNELS.put(key, webSocketSession);
        List<String> channelSessionIdList = SCREEN_CHANNELS_SESSIONID.get(channelName);
        if (channelSessionIdList == null) {
            channelSessionIdList = Lists.newArrayList();
        }
        channelSessionIdList.add(sessionId);
        SCREEN_CHANNELS_SESSIONID.put(channelName, channelSessionIdList);
    }

    public static void delScreeChannel(String channelName, WebSocketSession webSocketSession) {
        String sessionId = webSocketSession.getId();
        String key = getScreenChannelKey(channelName, sessionId);
        SCREEN_CHANNELS.remove(key);
        List<String> channelSessionIdList = SCREEN_CHANNELS_SESSIONID.get(channelName);
        channelSessionIdList.remove(sessionId);
    }

    public static int screenSize(String channelName) {
        List<String> channelSessionIdList = SCREEN_CHANNELS_SESSIONID.get(channelName);
        return channelSessionIdList == null ? 0 : channelSessionIdList.size();
    }

    public static boolean isExsitScreenChannel(String channelName, WebSocketSession webSocketSession) {
        String sessionId = webSocketSession.getId();
        String key = getScreenChannelKey(channelName, sessionId);
        return SCREEN_CHANNELS.containsKey(key);
    }

    public static List<WebSocketSession> getAllScreenChannel(String channelName) {
        List<String> channelSessionIdList = SCREEN_CHANNELS_SESSIONID.get(channelName);
        List<WebSocketSession> webSocketSessionList = Lists.newArrayList();
        if (channelSessionIdList == null) {
            return webSocketSessionList;
        }
        List<String> invalidChannelSessionId = new ArrayList<String>();
        for (String sessionId : channelSessionIdList) {
            String key = getScreenChannelKey(channelName, sessionId);
            WebSocketSession webSocketSession = SCREEN_CHANNELS.get(key);
            if (webSocketSession == null) {
                invalidChannelSessionId.add(sessionId);
                continue;
            }
            webSocketSessionList.add(webSocketSession);
        }
        if (invalidChannelSessionId.size() > 0) {
            channelSessionIdList.removeAll(invalidChannelSessionId);
        }
        return webSocketSessionList;
    }

    private static String getScreenChannelKey(String channelName, String sessionId) {
        return channelName + "_" + sessionId;
    }
}
